/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cheetah.youbet.download;

import com.itextpdf.text.pdf.PdfReader;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.cheetah.youbet.beans.Avvenimento;
import org.cheetah.youbet.beans.Palinsesto;
import org.cheetah.youbet.helper.IncontroHelper;
import org.cheetah.youbet.sql.Database;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 *
 * @author edoardo
 */
public class PianetaScommesseDownload {

    private static List<String> startTableText = new ArrayList<String>();

    static {
        startTableText.add("CALCIO");
        startTableText.add("BASKET");
        startTableText.add("TENNIS");
        startTableText.add("VOLLEY");
        startTableText.add("FOOTBA");
        startTableText.add("RUGBY");
        startTableText.add("HOCKEY");
        startTableText.add("MOTO");
        startTableText.add("PMANO");
        startTableText.add("BASEBA");

    }

    private static Avvenimento createAvvenimento(Elements ris) {
        if (ris.size() > 0) {
            String avv = ris.get(0).text();
            String desc = ris.get(1).text();
            String ora = ris.get(2).text();
            String risultato = ris.get(3).text();
//            System.out.println("---------> " + risultato + " <-----------");
            if (risultato.indexOf("/") != -1) {
                String risTempo1 = risultato.substring(0, risultato.indexOf("/"));
                String risFinale = risultato.substring(risultato.indexOf("/") + 1);
                Avvenimento avvenimento = new Avvenimento();
                avvenimento.setDescrizione(desc);
                avvenimento.setNumero(avv);
                avvenimento.setRisultatoPrimoTempo(risTempo1);
                avvenimento.setRisultatoSecondoTempo(risFinale);
                return avvenimento;
            }

        }
        return null;
    }

    private static List<Avvenimento> createAvvenimentos(Elements rows, String competizione) {
        List<Avvenimento> avvenimentos = new ArrayList<Avvenimento>();
        //salto la prima riga che è l'intestazione
        for (int i = 1; i < rows.size(); i++) {
            Elements ris1 = rows.get(i).getElementsByClass("testo_r1");
            Elements ris2 = rows.get(i).getElementsByClass("testo_r2");
            Avvenimento avvenimento1 = createAvvenimento(ris1);
            Avvenimento avvenimento2 = createAvvenimento(ris2);
            if (avvenimento1 != null) {
                avvenimento1.setNomeCompetizione(competizione);
                avvenimentos.add(avvenimento1);
            }
            if (avvenimento2 != null) {
                avvenimento2.setNomeCompetizione(competizione);
                avvenimentos.add(avvenimento2);
            }
        }

        return avvenimentos;
    }

    public void downloadScores() throws Exception {
        List<Date> dates = new ArrayList<Date>();
        Connection con = Database.getConnection();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(getMaxDate(Database.getConnection()));
//        calendar.set(Calendar.YEAR, 2012);
//        calendar.set(Calendar.DAY_OF_MONTH, 22);
//        calendar.set(Calendar.MONTH, 10);

        Calendar today = Calendar.getInstance();
        today.setTime(new Date());
        String _date = "";
        while (!(_date = dateToString(calendar.getTime(), "dd/MM/yyyy")).equals(dateToString(today.getTime(), "dd/MM/yyyy"))) {
//            if (!IncontroHelper.findMatchesByDate(con, calendar)) {
                dates.add(calendar.getTime());
//            }
            calendar.add(Calendar.DAY_OF_MONTH, 1);

        }
//        dates.remove(dates.size()-1);
        con.setAutoCommit(false);
        Map<String, String> presentiSuDB = new HashMap<String, String>();
        List<String> errori = new ArrayList<String>();
        try {
            int row = 0;

            first:
            for (Date date : dates) {
                List<Palinsesto> palinsesti = getRisultatiHtml(dateToString(date, "yyyyMMdd"));
                for (Palinsesto palinsesto : palinsesti) {

//                Map<String, Palinsesto> palinsesti = getRisultatiPdf(dateToString(date, "YY_MM_dd"), true);
//                for (Iterator<String> it = palinsesti.keySet().iterator(); it.hasNext();) {
//                    String key = it.next();
//                    Palinsesto palinsesto = palinsesti.get(key);
//                    System.out.println(palinsesto);
                    if (palinsesto != null) {
//                        System.out.println(palinsesto);
                        for (Avvenimento avvenimento : palinsesto.getAvvenimentos()) {
                            String _key_ = new StringBuilder(palinsesto.getNumero()).append("|").append(avvenimento.getNumero()).toString();
                            if (!presentiSuDB.containsKey(_key_)) {
                                IncontroHelper.insertIncontro(con, palinsesto, avvenimento, date);

                                row++;
//                            if (row == maxNumberRowsToCommit) {
                                try {

                                    row = 0;

//                            }
                                    presentiSuDB.put(_key_, "");
                                } catch (Exception error) {
                                    errori.add(error.getMessage() + "\n\t" + avvenimento);
                                }
                            }
                        }
                    }
                }
                con.commit();

            }
            con.commit();
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Rollback....");
            if (con != null && !con.isClosed()) {
                con.rollback();
                con.close();
            }

        }
        if (errori.size() > 0) {
            System.out.println(errori);
        }
    }

    private List<Palinsesto> getRisultatiHtml(String data) throws IOException {
        int anno = Integer.parseInt(data.substring(0, 4));
        int mese = Integer.parseInt(data.substring(4, 6));
        int giorno = Integer.parseInt(data.substring(6));

        System.out.println("Risultatati del " + giorno + "/" + mese + "/" + anno);
        Document doc = Jsoup.connect("http://statistiche.pianetascommesse.it/risultati.php")
                .data("anno_corrente", Integer.toString(anno))
                .data("mese_corrente", Integer.toString(mese))
                .data("giorno_corrente", Integer.toString(giorno))
                .data("cerca_risultati", "Visualizza")
                .post();
        Elements elements = doc.getElementsByTag("table");
        List<Palinsesto> palinsestos = new ArrayList<Palinsesto>();
        for (Iterator<Element> it = elements.iterator(); it.hasNext();) {
            Element element = it.next();
            Elements titolo3 = element.getElementsByClass("titolo3");
            if (titolo3.text() != null && titolo3.text().trim().equalsIgnoreCase("calcio")) {
                Palinsesto p = new Palinsesto();
                Elements titolo2 = element.getElementsByClass("titolo2");
                String txt = titolo2.text();
                String competizione = txt.substring(txt.indexOf("-") + 1).trim();
                String palinsesto = txt.substring(0, txt.indexOf("-"));
                palinsesto = palinsesto.substring(palinsesto.indexOf(" ") + 1).trim();
                p.setCompetizione(competizione);
                p.setNumero(palinsesto);
                element = it.next();//prossima tabella con i risultati
                Elements rows = element.getElementsByTag("tr");

                List<Avvenimento> avvenimentos = createAvvenimentos(rows, competizione);
                p.setAvvenimentos(avvenimentos);

                palinsestos.add(p);
                System.out.println(competizione);
                System.out.println("\t" + p);
            }
        }
        
        return palinsestos;
    }

    private static Date getMaxDate(Connection con) throws SQLException {
        try {
            String sqlMax = Database.getSql("database.maxdate.incontro");
            Date maxDate = null;
            PreparedStatement pstmt = con.prepareStatement(sqlMax);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                maxDate = rs.getDate(1);
            }
            rs.close();
            pstmt.close();

            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH, 20);
            calendar.set(Calendar.MONTH, 7);
            calendar.set(Calendar.YEAR, 2012);

            return maxDate == null ? new Date(calendar.getTime().getTime()) : maxDate;
        } finally {
            if (con != null && !con.isClosed()) {
                con.close();
            }
        }

    }

    public static void main(String[] args) throws Exception {
//        Document doc = Jsoup.connect("http://www.sisal.it/PalinsestoNuovo/pubblico/menu/sport.jsp?sezione=sport&filtro=tutti")
//                .post();
        Document doc = Jsoup.connect("http://Documenwww.stats.betradar.com/s4/?clientid=205&clientmatchid=14600-1&treemenu=false").get();
        System.out.println(doc);
    }

//    public static Map<String, Palinsesto> getRisultatiPdf(String data) throws Exception {
//        return getRisultatiPdf(data, false);
//    }
    public static Map<String, Palinsesto> getRisultatiPdf(String data, boolean keepTemp) throws Exception {
        Map<String, Palinsesto> palinsesti = new HashMap<String, Palinsesto>();
        System.out.println(data);
        try {
            String destDir = System.getProperty("user.home") + File.separator + "TEMP_RISULTATI";
            File fDestDir = new File(destDir);
            if (!fDestDir.exists()) {
                fDestDir.mkdir();
            }
            String fileTxt = destDir + File.separator + data + ".txt";
            List<String> pages = new ArrayList<String>();
            if (!keepTemp || !new File(fileTxt).exists()) {
                URL url = new URL("http://statistiche.pianetascommesse.it/download/pdf/risultati/" + data + "_RIS.pdf");//TODO 
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                InputStream pdfIn = con.getInputStream();
                PdfReader reader = new PdfReader(pdfIn);
                int n = reader.getNumberOfPages();
                OutputStream out = keepTemp ? new FileOutputStream(fileTxt) : null;

                for (int i = 0; i < n; i++) {
                    StringBuffer sbLine = new StringBuffer();
//            sbLine.append("Page: " + (i + 1)).append("\n\n");
                    byte[] b = reader.getPageContent(i + 1);
                    BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(b)));
                    String line = null;
                    while ((line = br.readLine()) != null) {
                        if (line.indexOf("Tj") != -1) {
                            line = line.substring(line.indexOf("(") + 1, line.indexOf(")"));

                            sbLine.append(new String(line.getBytes(), "UTF-8")).append("\n");
                        }

                    }
                    pages.add(sbLine.toString());
                    if (out != null) {
                        out.write(sbLine.toString().getBytes("UTF-8"));
                    }
                }

                pdfIn.close();
                if (out != null) {
                    out.flush();
                    out.close();
                }
            }
            if (keepTemp && pages.size() == 0) {
                pages.add(IOUtils.toString(new FileInputStream(fileTxt)));
            }
//        System.out.println(sbLine);
            for (String sbLine : pages) {

                //secondo ciclo che estrae i dati e li raggruppa in per palinsesto
                BufferedReader br = new BufferedReader(new StringReader(sbLine));

                String line = "";

                while (line != null) {
                    String lineBefore = line;
                    line = br.readLine();
                    if (lineBefore.equalsIgnoreCase("calcio") && line.toLowerCase().indexOf("pal.") != -1) {
                        String num = line.substring(line.toLowerCase().indexOf("pal.") + "pal.".length()).trim();
                        Palinsesto palinsesto = palinsesti.get(num);
                        if (palinsesto == null) {
                            palinsesto = new Palinsesto();
                        }
                        palinsesto.setNumero(num);
                        line = br.readLine();//passo al rigo successivo
                        String competizione = line;
                        while (line != null && !line.toLowerCase().equals("risultato")) {
                            line = br.readLine();
                        }
                        //dopo la colonna "RISULTATO" ci sono i veri e propri risultati
//                while (!(line = br.readLine()).equals("CALCIO")) {
                        while (!startTableText.contains((line = br.readLine()))) {

                            Avvenimento avvenimento = new Avvenimento();
                            avvenimento.setNomeCompetizione(competizione);
                            avvenimento.setNumero(line);
                            avvenimento.setDescrizione(br.readLine());
                            String risPrimoTempo = br.readLine();
                            String risSecondoTempo = "";
                            if (risPrimoTempo == null) {
                                break;
                            }
                            if (risPrimoTempo.indexOf("/") != -1) {
                                risSecondoTempo = risPrimoTempo.substring(risPrimoTempo.indexOf("/") + 1);

                                risPrimoTempo = risPrimoTempo.substring(0, risPrimoTempo.indexOf("/"));

                                if (risSecondoTempo.toLowerCase().indexOf("dts") != -1 || risSecondoTempo.toLowerCase().indexOf("d.t.s.") != -1 || risSecondoTempo.toLowerCase().indexOf("d.t.s") != -1) {
                                    //il risultato del secondo tempo è uguale a quello del primo
                                    if (risSecondoTempo.startsWith("\\(")) {
                                        risSecondoTempo = risPrimoTempo;
                                    }
                                    if (risSecondoTempo.toLowerCase().indexOf("\\(") > 0) {
                                        risSecondoTempo = risSecondoTempo.substring(0, risSecondoTempo.indexOf("\\(")).trim();
                                    }
                                }

                                if (risSecondoTempo.toLowerCase().indexOf("dcr") != -1 || risSecondoTempo.toLowerCase().indexOf("d.c.r.") != -1 || risSecondoTempo.toLowerCase().indexOf("d.c.r") != -1) {
                                    //il risultato del secondo tempo è uguale a quello del primo
                                    if (risSecondoTempo.startsWith("\\(")) {
                                        risSecondoTempo = risPrimoTempo;
                                    }
                                    if (risSecondoTempo.indexOf("\\(") > 0) {
                                        risSecondoTempo = risSecondoTempo.substring(0, risSecondoTempo.indexOf("\\(")).trim();
                                    }
                                }
                                if (risSecondoTempo.toLowerCase().indexOf("dr") != -1) {
                                    //il risultato del secondo tempo è uguale a quello del primo
                                    if (risSecondoTempo.startsWith("\\(") || risSecondoTempo.endsWith("dr") || risSecondoTempo.endsWith("d.r.") || risSecondoTempo.endsWith("d.r")) {
                                        risSecondoTempo = risPrimoTempo;
                                    }
                                    if (risSecondoTempo.indexOf("\\(") > 0) {
                                        risSecondoTempo = risSecondoTempo.substring(0, risSecondoTempo.indexOf("\\(")).trim();
                                    }
                                }
                                if (risSecondoTempo.toLowerCase().indexOf("/") != -1) {
                                    risSecondoTempo = risSecondoTempo.substring(0, risSecondoTempo.indexOf("/"));
                                }
                            }
                            avvenimento.setRisultatoPrimoTempo(risPrimoTempo);
                            avvenimento.setRisultatoSecondoTempo(risSecondoTempo);
                            if (risSecondoTempo.indexOf("-") != -1) {
                                palinsesto.addAvvenimento(avvenimento);
                            }
//                        System.out.println(avvenimento);
                        }

                        palinsesti.put(num, palinsesto);
                    }

//                    System.out.println(line);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("No scores in " + data);
        }
        //prelevo la pagina HTML dei risultati
//        Document doc = Jsoup.connect("http://statistiche.pianetascommesse.it/risultati.php").get();
//        Elements elements = doc.getElementsByTag("table");
//        for (Iterator<Element> it = elements.iterator(); it.hasNext();) {
//            Element element = it.next();
//            System.out.println(element.getElementsByClass("titolo3"));
//        }
        return palinsesti;
    }

    private static String dateToString(Date date, String pattern) {
        SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance();
        sdf.applyPattern(pattern);
        String p = sdf.format(date);
        return p;
    }

}
